﻿/*
 
    This file is part of AnkhBG.

    AnkhBG is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    AnkhBG is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with AnkhBG.  If not, see <http://www.gnu.org/licenses/>.
 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

using Glider.Common.Objects;

namespace AnkhBG
{
    public class Statistics
    {
        #region Public Fields

        public StatsForm Window;

        public int AVMarks
        {
            get
            {
                GBagItem[] bagitems = GContext.Main.Me.GetBagCollection(GItemBagAction.Unknown);
                foreach (GBagItem item in bagitems)
                {
                    if (item.Item.Name == "Alterac Valley Mark of Honor")
                        return item.Item.StackSize;
                }
                return 0;
            }
        }

        public int ABMarks
        {
            get
            {
                GBagItem[] bagitems = GContext.Main.Me.GetBagCollection(GItemBagAction.Unknown);
                foreach (GBagItem item in bagitems)
                {
                    if (item.Item.Name == "Arathi Basin Mark of Honor")
                        return item.Item.StackSize;
                }
                return 0;
            }
        }

        public int WGMarks
        {
            get
            {
                GBagItem[] bagitems = GContext.Main.Me.GetBagCollection(GItemBagAction.Unknown);
                foreach (GBagItem item in bagitems)
                {
                    if (item.Item.Name == "Warsong Gulch Mark of Honor")
                        return item.Item.StackSize;
                }
                return 0;
            }
        }

        public int EoTSMarks
        {
            get
            {
                GBagItem[] bagitems = GContext.Main.Me.GetBagCollection(GItemBagAction.Unknown);
                foreach (GBagItem item in bagitems)
                {
                    if (item.Item.Name == "Eye of the Storm Mark of Honor")
                        return item.Item.StackSize;
                }
                return 0;
            }
        }

        #endregion

        #region Private Fields

        private bool IsWindowOpen
        {
            get
            {
                return (Window != null && !Window.IsDisposed && Window.Visible);
            }
        }

        // Stats
        // PROPERTIES!!! LOTS OF EM!!!!
        private int _TotalHonor = 0;
        public int TotalHonor
        { get { return _TotalHonor; } }

        private int _TotalHonorKills = 0;
        public int TotalHonorKills
        { get { return _TotalHonorKills; } }

        private int _TotalKillingBlows = 0;
        public int TotalKillingBlows
        { get { return _TotalKillingBlows; } }

        private int _TotalBattlegrounds = 0;
        public int TotalBattlegrounds
        { get { return _TotalBattlegrounds; } }

        private int _TotalWins = 0;
        public int TotalWins
        { get { return _TotalWins; } }

        private int _TotalLosses = 0;
        public int TotalLosses
        { get { return _TotalLosses; } }



        private int _SessionHonor = 0;
        public int SessionHonor
        {
            get { return _SessionHonor; }
            set
            {
                if (value != 0)
                    _TotalHonor += value - _SessionHonor;
                _SessionHonor = value;

                UpdateWindowStats();
            }
        }

        private int _SessionHonorKills = 0;
        public int SessionHonorKills
        {
            get { return _SessionHonorKills; }
            set
            {
                if (value != 0)
                    _TotalHonorKills += value - _SessionHonorKills;
                _SessionHonorKills = value;

                UpdateWindowStats();
            }
        }

        private int _SessionKillingBlows = 0;
        public int SessionKillingBlows
        {
            get { return _SessionKillingBlows; }
            set
            {
                if (value != 0)
                    _TotalKillingBlows += value - _SessionKillingBlows;
                _SessionKillingBlows = value;

                UpdateWindowStats();
            }
        }

        private int _SessionBattlegrounds = 0;
        public int SessionBattlegrounds
        {
            get { return _SessionBattlegrounds; }
            set
            {
                if (value != 0)
                    _TotalBattlegrounds += value - _SessionBattlegrounds;
                _SessionBattlegrounds = value;

                UpdateWindowStats();
            }
        }

        private int _SessionWins = 0;
        public int SessionWins
        {
            get { return _SessionWins; }
            set
            {
                if (value != 0)
                {
                    _TotalWins += value - _SessionWins;
                }
                _SessionWins = value;

                UpdateWindowStats();
            }
        }

        private int _SessionLosses = 0;
        public int SessionLosses
        {
            get { return _SessionLosses; }
            set
            {
                if (value != 0)
                {
                    _TotalLosses += value - _SessionLosses;
                }
                _SessionLosses = value;

                UpdateWindowStats();
            }
        }

        #endregion


        #region Constructors

        public Statistics()
        {
            GContext.Main.CombatLog += new GContext.GCombatLogHandler(CombatLogHandler);
        }

        ~Statistics()
        {
            try
            {
                if (GContext.Main != null && GContext.Main.IsGliderRunning)
                    GContext.Main.Debug("AnkhBG: Call: ~Statistics(); Start");

                if (Window != null && Window.IsDisposed)
                    Window.Dispose();

                GContext.Main.CombatLog -= new GContext.GCombatLogHandler(CombatLogHandler);

                if (GContext.Main != null && GContext.Main.IsGliderRunning)
                    GContext.Main.Debug("AnkhBG: Call: ~Statistics(); End");
            }
            catch (Exception e)
            {
                if (GContext.Main != null && GContext.Main.IsGliderRunning)
                    GContext.Main.Debug("AnkhBG: Statistics::~Statistics()::Exception: " + e.ToString());
            }
        }
        #endregion

        #region Public Methods
        // Looks when we receive Honor and adds it to the variables
        public void CombatLogHandler(string rawText)
        {
            if (Main.Instance.running)
            {
                string parsedText = CombatLogCleaner(rawText);

                if (parsedText.StartsWith("You have been awarded") && parsedText.EndsWith("honor points."))
                {
                    string pattern = @"([0-9]+)";
                    Match honorcalc = Regex.Match(parsedText, pattern);
                    if (honorcalc.Success)
                    {
                        int newHonor = Int32.Parse(honorcalc.Value);
                        SessionHonor += newHonor;
                    }
                }

                if (parsedText.Contains("honorable kill"))
                {
                    string pattern = @"([0-9]+)";
                    Match honorcalc = Regex.Match(parsedText, pattern);
                    if (honorcalc.Success)
                    {
                        int newHonor = Int32.Parse(honorcalc.Value);
                        SessionHonor += newHonor;
                        ++SessionHonorKills;
                    }
                }

                if (parsedText.StartsWith("You have slain "))
                    ++SessionKillingBlows;
            }
        }

        public void ShowWindow()
        {
            if (Window == null || Window.IsDisposed)
                Window = new StatsForm();

            Window.Show();
            UpdateWindowStats();

            // Update the Runtime whenever the Window opens
            if (Main.Instance.running)
            {
                TimeSpan Runtime = DateTime.Now - Main.Instance.starttime;
                Window.RuntimeLabel.Text = Runtime.Hours.ToString() + " Hours "
                                         + Runtime.Minutes.ToString() + " Minutes "
                                         + Runtime.Seconds.ToString() + " Seconds";
            }
            else
                Window.RuntimeLabel.Text = "0 Hours 0 Minutes 0 Seconds";

            Window.BringToFront();
        }

        // After a BG is finished we will try to see if we won or lost
        // by looking at the WorldStateScoreFrame
        public void GetStatsFromWorldScore()
        {
            GInterfaceObject obj = GContext.Main.Interface.GetByName("WorldStateScoreFrame");
            if (obj != null && obj.IsVisible)
            {
                ++SessionBattlegrounds;

                GInterfaceObject WinnerFrame = GContext.Main.Interface.GetByName("WorldStateScoreWinnerFrame");
                if (WinnerFrame != null)
                {
                    GInterfaceObject WinnerText = WinnerFrame.GetChildObject("WorldStateScoreWinnerFrameText");
                    if (WinnerText != null)
                    {
                        if (
                                (WinnerText.LabelText.Contains("Horde") && GContext.Main.Me.PlayerFaction == GPlayerFaction.Horde) ||
                                (WinnerText.LabelText.Contains("Alliance") && GContext.Main.Me.PlayerFaction == GPlayerFaction.Alliance)
                            )
                            ++SessionWins;
                        else
                            if (
                                (WinnerText.LabelText.Contains("Horde") && GContext.Main.Me.PlayerFaction == GPlayerFaction.Alliance) ||
                                (WinnerText.LabelText.Contains("Alliance") && GContext.Main.Me.PlayerFaction == GPlayerFaction.Horde)
                            )
                                ++SessionLosses;
                    }
                }
            }
        }

        // Resets all Session-values to 0
        public void ResetSession()
        {
            SessionHonor = 0;
            SessionHonorKills = 0;
            SessionKillingBlows = 0;
            SessionBattlegrounds = 0;
            SessionWins = 0;
            SessionLosses = 0;
        }

        #endregion

        #region Private Methods
        // Will clean up all the color-codes, link-codes etc. 
        // so we have parsed text like the text we see in WoW
        private string CombatLogCleaner(string rawText)
        {
            string sb = Regex.Replace(rawText, "\\|H[^|]+(?=|h)", "");
            sb = Regex.Replace(sb, "\\|c[^|].......", "");
            sb = sb.Replace("|h", "");
            sb = sb.Replace("|r", "");
            return sb;
        }

        private void UpdateWindowStats()
        {
            if (!IsWindowOpen)
                return;

            Window.HonorLabel.Text = SessionHonor.ToString();
            Window.HonorKillLabel.Text = SessionHonorKills.ToString();
            Window.KillingBlowLabel.Text = SessionKillingBlows.ToString();
            Window.BattlegroundLabel.Text = SessionBattlegrounds.ToString();
            Window.WinLabel.Text = SessionWins.ToString();
            Window.LossLabel.Text = SessionLosses.ToString();

            Window.TotalHonorLabel.Text = TotalHonor.ToString();
            Window.TotalHonorKillsLabel.Text = TotalHonorKills.ToString();
            Window.TotalKillingBlowsLabel.Text = TotalKillingBlows.ToString();
            Window.TotalBattlegroundsLabel.Text = TotalBattlegrounds.ToString();
            Window.TotalWinsLabel.Text = TotalWins.ToString();
            Window.TotalLossesLabel.Text = TotalLosses.ToString();

            Window.AVMarksLabel.Text = AVMarks.ToString();
            Window.ABMarksLabel.Text = ABMarks.ToString();
            Window.WGMarksLabel.Text = WGMarks.ToString();
            Window.EoTSMarksLabel.Text = EoTSMarks.ToString();

            Window.ResumeLayout(false);
        }

        #endregion 
    }
}
